[org 0x7c00]
[SECTION .data]
BOOT_MAIN_ADDR equ 0x500

[SECTION .text]
[BITS 16]
global boot_start
boot_start:
    ; 清屏
    mov ax, 3
    int 10h

    ; 加载setup到内存地址0x500处
    mov edi, BOOT_MAIN_ADDR
    mov ecx, 1 ; 从哪个扇区开始读, 起始是lba的地址
    mov bl, 2 ;  读几个扇区
    call read_hd

    ;  打印消息
    mov si, jmp_to_setup
    call print

    jmp BOOT_MAIN_ADDR

read_hd:
    mov dx, 0x1f2
    ;  读入扇区数
    mov al, bl
    out dx, al

    mov dx, 0x1f3
    mov al, cl
    out dx, al

    mov dx, 0x1f4
    mov al, ch
    out dx, al

    mov dx, 0x1f5
    shr ecx, 16
    mov al, cl
    out dx, al

    mov dx, 0x1f6
    shr cx, 8
    and cl, 0fh
    ;  高4位 从低到高分别是
    ;  0表示主盘， 如果是1表示从盘
    ;  1固定为1
    ;  1表示LBA模式，如果是0则表示CHS模式
    ;  1固定为1
    mov al, 0b1110_0000
    or al, cl
    out dx, al

    mov dx, 0x1f7
    ;  0x20表示读
    mov al, 0x20
    out dx, al

    ;  要读取的扇区数
    mov cl, bl
    ;  老师给的代码没有下面这一行，为了严谨，起始需要加上这个
    mov ch, 0
.start_read:
    push cx
    call wait_hd_prepare
    call read_hd_data

    pop cx
    loop .start_read

    ret

wait_hd_prepare:
    mov dx, 0x1f7
.check:
    in al, dx
    ;  看最高位是不是1
    and al, 0b1000_0000
    cmp al, 0b0000_0000
    ;  起始也可以替换成
    ;  shr al, 7
    ;  cmp al, 0
    ;  如果不是1，就重复执行
    jnz .check
    ret

read_hd_data:
    mov dx, 0x1f0
    mov cx, 256
.read_data:
    in ax, dx
    mov word [edi], ax
    add edi, 2
    loop .read_data
    
    ret

;  打印信息
;  打印的首字符放在si中的
print:
    mov ah, 0x0e
    mov bh, 0
    mov bl, 0x1
.continue_print:
    mov al, [si]
    cmp al, 0
    jz .done
    int 0x10

    inc si
    jmp .continue_print
.done:
    ret

jmp_to_setup:
    db "jump to setup...", 10, 13, 0

times 510 - ($ - $$) db 0
dw 0xaa55